// This is a 12 bit adc
/*
***************************************************************************************************
*   ADS7844.c
*   ADS7844 驱动文件，提供了函数读取8个通道的电压值。
*
***************************************************************************************************
*/

#include "main.h"   // 提供引脚宏定义
#include "ADS7844.h" // 提供CFG寄存器结构定义

#include "struct_typedef.h"

static
void naive_delay_us(uint16_t nus)
{
    uint32_t i,j;
    uint8_t nothing;
    nothing  = 0;
    for(i = 0; i < nus; i++)
    {
        for(j = 0; j < ((uint32_t)(1)); j++)
        {
                nothing ++ ;
        }
    }
}

static inline
void reset_sck(void)
{
    HAL_GPIO_WritePin(HAND_ADS7844_SCK_GPIO_Port,HAND_ADS7844_SCK_Pin,GPIO_PIN_RESET);
}

static inline
void set_sck(void)
{
    HAL_GPIO_WritePin(HAND_ADS7844_SCK_GPIO_Port,HAND_ADS7844_SCK_Pin,GPIO_PIN_SET);
}

static inline
void set_cs(void)
{
    HAL_GPIO_WritePin(HAND_ADS7844_CS_GPIO_Port,HAND_ADS7844_CS_Pin,GPIO_PIN_SET);
}

static inline
void reset_cs(void)
{
    HAL_GPIO_WritePin(HAND_ADS7844_CS_GPIO_Port,HAND_ADS7844_CS_Pin,GPIO_PIN_RESET);
}

static inline
void delay_moment(void)
{
    naive_delay_us(1);
}

static inline
void write_MOSI(uint16_t signal)
{
    HAL_GPIO_WritePin(HAND_ADS7844_MOSI_GPIO_Port,HAND_ADS7844_MOSI_Pin,(GPIO_PinState)(signal));
}

static inline
uint16_t read_MISO(void)
{
    return (uint16_t) (HAL_GPIO_ReadPin(HAND_ADS7844_MISO_GPIO_Port,HAND_ADS7844_MISO_Pin));
}


static uint8_t ADS7844_overflow_flag = 0;    // 溢出标志
static uint16_t rec_data;                          // 获取到的数据

// 通道名对应的配置选择号码
static uint8_t channel_config[8]={
    0,4,1,5,2,6,3,7
};

static ADS7844_control_s send_to_adc = {
    0, // power down between conversion
    // 3, // always power up
    1, // single end
    // 0, // diff
    0, // reserved
    7, // choose channel 7
    1, // start bit
};

/****************************************************************************
函数名	： read_ADS7844_voltage
功能	： 从ADS7844一个端口的读取电压值
参数	： channel - 物理标记的通道号码，取值为0,1,2,3,4,5,6,7
返回值	： voltage 读取到的电压，取值为0~参考电压
****************************************************************************/
float read_ADS7844_voltage (uint8_t channel)
{
    uint8_t i,j;
    float voltage;
    uint8_t send_buf;
    send_to_adc.channel = channel_config[channel];
    send_buf = *((uint8_t *)(&send_to_adc));

    reset_sck();
    reset_cs();
    for(i = 0;i<8;i++)
    {
        write_MOSI((send_buf & 0x80)>>7); // MSB is first
        send_buf <<=1;
        delay_moment();
        set_sck();
        delay_moment();
        reset_sck();
        delay_moment();
    }

    rec_data = 0;
    for(j = 0;j<16;j++)
    {
        set_sck();
        rec_data <<=1;
        rec_data |= read_MISO();
        delay_moment();
        reset_sck();
        delay_moment();
    }
    set_cs();
    write_MOSI(0);
    rec_data = rec_data & 0x7FFF;
    rec_data = rec_data >> 3;
    ADS7844_overflow_flag = (rec_data == 0xFFF) ? 1 : 0;
    voltage = ((double)(rec_data & 0xFFF)) / 0xFFF * 5.0;
    return voltage;
}

/****************************************************************************
函数名	： get_ADS7844_overflow
功能	： 判定ADS7844上一次读取电压时是否溢出
参数	： 无
返回值	： ADS7844_overflow_flag - 为1时表示溢出了，为0时表示没有溢出
****************************************************************************/
uint8_t get_ADS7844_overflow(void)
{
    return ADS7844_overflow_flag;
}
